package org.mbds.wolf.android.hce;

import java.util.HashMap;

import org.mbds.wolf.android.hce.seservice.WolfHceService;
import org.mbds.wolf.exception.ByteArrayToHexaStringException;
import org.mbds.wolf.seql.APDUModel;
import org.mbds.wolf.seql.APDUResponse;
import org.mbds.wolf.seql.ISeqlCallBack;
import org.mbds.wolf.seql.exceptions.APDUError;
import org.mbds.wolf.tools.BytesTool;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

/**
 * SeqlProcessApduCommandThread
 * @author alesas
 *
 */
public class SeqlProcessApduCommandThread { //implements Runnable {

    public final static String KEY_MSG 			= "msg";
    public final static String KEY_INDEX 		= "index";
    public final static String KEY_DATA 		= "data";
    public final static String KEY_COMMAND_ID 	= "cmdId";
    public final static String KEY_NB_COMMAND 	= "nbCmd";
    
	public final static String MSG_ERR_CMD_UNCOMPLETED 		= "Command was uncompleted....";

	
	private int currentCommandId;
	private int currentIndex;
	private int currentNbCommands;
	private String currentField;
	private byte[] currentApduCommand;
	private Context context;

	// store incoming responses to notify callback
	private static ISeqlCallBack callback;
	private static HashMap<String, Object> results;
	private static BroadcastReceiver receiver = new SeqlHceReceiver();

	SeqlProcessApduCommandThread(Context ctx, ISeqlCallBack callback, int cmdId, int index, int nbCommands, String field, byte[] apduCommand)
	{
		SeqlProcessApduCommandThread.callback = callback;
		this.context = ctx;
		this.currentCommandId = cmdId;
		this.currentIndex = index;
		this.currentNbCommands = nbCommands;
		this.currentField = field;
		this.currentApduCommand = apduCommand;
		IntentFilter filter = new IntentFilter(WolfHceService.ACTION_MSG_RESPONSE_APDU);
		((Context)context).registerReceiver(receiver, filter);
//		new Thread(this).start();
//	}
//
//	@Override
//	public void run() {
		Bundle extras = new Bundle();
		extras.putString(KEY_MSG, currentField);
		extras.putInt(KEY_COMMAND_ID, currentCommandId);
		extras.putInt(KEY_INDEX, currentIndex);
		extras.putInt(KEY_NB_COMMAND, currentNbCommands);
		extras.putByteArray(WolfHceService.KEY_COMMAND_APDU, currentApduCommand);
		Intent intent = new Intent();
		intent.setAction(WolfHceService.ACTION_MSG_COMMAND_APDU);
		intent.putExtras(extras);
		context.sendBroadcast(intent);
	}

	/**
	 * WolfHceReceiver:
	 * This class is intended to receive APDU instructions to be processed
	 */
	public static class SeqlHceReceiver extends BroadcastReceiver 
	{

		@Override
		public void onReceive(Context context, Intent intent) 
		{
			if (intent != null && intent.getAction().equals(WolfHceService.ACTION_MSG_RESPONSE_APDU)) 
			{
				Bundle extras = intent.getExtras();
				if (extras != null) 
				{
					int index = extras.getInt(KEY_INDEX);
					int cmdId = extras.getInt(KEY_COMMAND_ID);
					
					if (index==0)
					{
						results = new HashMap<String, Object>();
					}
					try 
					{
						byte[] responseReceived = extras
								.getByteArray(WolfHceService.KEY_RESPONSE_APDU);
						if (responseReceived!=null && responseReceived.length>0)
							try 
							{
								Log.i("SeqlHceController",
										"Response received: "
												+ BytesTool
														.byteArrayToHexString(responseReceived));
							} 
							catch (ByteArrayToHexaStringException e) 
							{
								e.printStackTrace();
							}

						APDUResponse resp = new APDUResponse();
						resp.setResponse(responseReceived);
						byte[] apduData = resp.getData();

						if (apduData != null && apduData.length > 0 && callback != null) 
						{
							if (!APDUModel.isResponseSucceded(responseReceived)) 
							{
								if (APDUModel.isPinRequired(responseReceived)) 
								{
									callback.onPINRequired();

								} 
								else 
								{
									callback.onAPDUError(new APDUError(MSG_ERR_CMD_UNCOMPLETED,responseReceived));
								}
							} 
							else 
							{
								results.put(extras.getString(KEY_MSG), new String(resp.getData()));
							}
						}
						else
						{
							callback.onAPDUError(new APDUError(MSG_ERR_CMD_UNCOMPLETED,responseReceived));						
						}

						if (results != null  && callback != null) 
						{
							int nbCommands = extras.getInt(KEY_NB_COMMAND);
							
							if (index+1>=nbCommands)
							{
								callback.onResponse(results, cmdId);
							}
						}
					} 
					catch (Exception e) 
					{
						e.printStackTrace();
					}
				}
			}
		}

	};	
}
